Skip to content

fix: compress JSON/buffer bodies in beforeResponse (#8, #5)#17

Merged
CodeDredd merged 1 commit into
mainfrom
fix/nitro-json-body
Jun 9, 2026
Merged

fix: compress JSON/buffer bodies in beforeResponse (#8, #5)#17
CodeDredd merged 1 commit into
mainfrom
fix/nitro-json-body

Conversation

@CodeDredd

Copy link
Copy Markdown
Owner

Problem

compress() guarded on typeof response.body === 'string', so anything that isn't a string was silently left uncompressed. In Nitro's beforeResponse hook (the one that also fires for /server/api and SWR/ISR cached routes), the body is the raw handler return value — for a JSON endpoint that's a plain object, not a string. Result: API/cached responses were never compressed (#8), and there was no documented way to compress cached responses (#5).

Changes

  • compress() now handles non-string bodies:
    • string → as before
    • Buffer / Uint8Array / ArrayBuffer → compressed as-is
    • plain JSON-serializable value (object/array) → serialized and tagged application/json (mirroring how h3 serializes objects)
    • streams / empty / non-serializable → skipped (left untouched, so binary assets aren't mangled)
  • README: new "Cached routes (SWR / ISR) and /server/api" section documenting the beforeResponse hook approach, with a note on content-type guarding.
  • Tests: object-body compression on both the h3 v1 app hook (onBeforeResponse) and the mutable/mockEvent path, for gzip and brotli.

Note: the h3 v2 compression() middleware already handled JSON bodies (via toResponse); this fix targets the v1 / Nitro mutable-response path.

Verified locally against both h3 v1 and v2; the CI matrix covers node 18/20 × h3 v1/v2.

Closes #8
Closes #5

🤖 Generated with Claude Code

`compress` only handled string bodies, so `/server/api` responses (plain
objects) and other non-string bodies were never compressed via the
`beforeResponse` hook.

- compress string, Buffer/Uint8Array/ArrayBuffer and JSON (object) bodies;
  objects are serialized and tagged as `application/json` like h3 does, while
  streams/empty bodies are skipped
- document the `beforeResponse` hook for SWR/ISR cached routes and `/server/api`
- tests for object bodies on both the h3 v1 app hook and the mutable path

Closes #8
Closes #5

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@CodeDredd CodeDredd merged commit 6585e6c into main Jun 9, 2026
9 checks passed
@CodeDredd CodeDredd deleted the fix/nitro-json-body branch June 9, 2026 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

beforeResponse hook does not work for Nuxt3 /server/api Compression with Nuxt swr cache

1 participant